// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Matteo Perotti <mperotti@iis.ee.ethz.ch>
//         Basile Bougenot <bbougenot@student.ethz.ch>

#include "vector_macros.h"
#include "float_macros.h"

// Simple random test with similar values
void TEST_CASE1(void) {
  VSET(16, e16, m1);
  //               0.3474, -0.9888,  0.2810,  0.4199,  0.1704, -0.3772,  0.2998,  0.7871, -0.2527, -0.8618,  0.2646,  0.5488, -0.3184, -0.3508, -0.3589, -0.3914
  VLOAD_16(v2,     0x358f,  0xbbe9,  0x347f,  0x36b8,  0x3174,  0xb609,  0x34cc,  0x3a4c,  0xb40b,  0xbae5,  0x343c,  0x3864,  0xb518,  0xb59d,  0xb5be,  0xb643);
  //               0.0417,  0.3862, -0.9619, -0.5659,  0.1731,  0.4827,  0.7334, -0.7271, -0.9814,  0.8003, -0.4836,  0.5234, -0.8540, -0.2036, -0.8823,  0.2603
  VLOAD_16(v3,     0x2958,  0x362e,  0xbbb2,  0xb887,  0x318a,  0x37b9,  0x39de,  0xb9d1,  0xbbda,  0x3a67,  0xb7bd,  0x3830,  0xbad5,  0xb284,  0xbb0f,  0x342a);
  //              -0.2739,  0.2146,  0.5264, -0.8853,  0.8877, -0.6748, -0.7563, -0.9634,  0.7451, -0.5166,  0.0698,  0.4790, -0.0681, -0.9746,  0.2129,  0.9072
  VLOAD_16(v1,     0xb462,  0x32de,  0x3836,  0xbb15,  0x3b1a,  0xb966,  0xba0d,  0xbbb5,  0x39f6,  0xb822,  0x2c77,  0x37aa,  0xac5b,  0xbbcc,  0x32d0,  0x3b42);
  asm volatile("vfnmsac.vv v1, v2, v3");
  //              -0.2883,  0.5967,  0.7969, -0.6475,  0.8584, -0.4927, -0.9761, -0.3911,  0.4971,  0.1733,  0.1978,  0.1917, -0.3401, -1.0459, -0.1038,  1.0088
  VCMP_U16(1, v1,  0xb49d,  0x38c6,  0x3a60,  0xb92e,  0x3ade,  0xb7e2,  0xbbcf,  0xb642,  0x37f4,  0x318a,  0x3254,  0x3223,  0xb570,  0xbc2f,  0xaea4,  0x3c09);

  VSET(16, e32, m1);
  //               0.11577118, -0.10074481,  0.13861528,  0.44782066,  0.42196107, -0.67597556,  0.34948668, -0.87903690, -0.34136006, -0.19722189,  0.76997000, -0.68663412,  0.45603558,  0.60629857, -0.86984915, -0.08019307
  VLOAD_32(v2,     0x3ded1971,  0xbdce534c,  0x3e0df12a,  0x3ee548c0,  0x3ed80b48,  0xbf2d0cbc,  0x3eb2efeb,  0xbf610890,  0xbeaec6bf,  0xbe49f489,  0x3f451cc1,  0xbf2fc741,  0x3ee97d7f,  0x3f1b3662,  0xbf5eae6f,  0xbda43c43);
  //              -0.38970658,  0.40460527,  0.69067985, -0.98108912,  0.47494572, -0.34277225, -0.54462087, -0.90492284,  0.60100728, -0.02819708, -0.46859986,  0.87238866,  0.46812481,  0.49922746,  0.97036403,  0.04279163
  VLOAD_32(v3,     0xbec7879f,  0x3ecf286c,  0x3f30d065,  0xbf7b28a8,  0x3ef32c16,  0xbeaf7fd8,  0xbf0b6c46,  0xbf67a906,  0x3f19db9d,  0xbce6fd92,  0xbeefec52,  0x3f5f54dd,  0x3eefae0e,  0x3eff9abe,  0x3f7869c7,  0x3d2f4647);
  //               0.79804420, -0.70010293, -0.51047552,  0.38566175,  0.15318950,  0.15531392, -0.20705318, -0.82493448,  0.12047531,  0.57526720,  0.23939800, -0.19725421,  0.15403098,  0.03931713, -0.45930895, -0.15395784
  VLOAD_32(v1,     0x3f4c4ca0,  0xbf3339f2,  0xbf02ae86,  0x3ec57575,  0x3e1cddb5,  0x3e1f0a9d,  0xbe5405c0,  0xbf532ee8,  0x3df6bbc3,  0x3f1344b6,  0x3e7524c0,  0xbe49fd02,  0x3e1dba4c,  0x3d210b00,  0xbeeb2a8b,  0xbe1da720);
  asm volatile("vfnmsac.vv v1, v2, v3");
  //               0.84316099, -0.65934104, -0.60621428,  0.82501376, -0.04721911, -0.07639174, -0.01671545, -1.62039506,  0.32563519,  0.56970614,  0.60020584,  0.40175763, -0.05945060, -0.26336378,  0.38476136, -0.15052626
  VCMP_U32(2, v1,  0x3f57d966,  0xbf28ca93,  0xbf1b30dc,  0x3f53341a,  0xbd4168d3,  0xbd9c7345,  0xbc88eed4,  0xbfcf691b,  0x3ea6b9a8,  0x3f11d843,  0x3f19a717,  0x3ecdb32c,  0xbd738277,  0xbe86d79e,  0x3ec4ff71,  0xbe1a238e);

  VSET(16, e64, m1);
  //              -0.1779684802061718,  0.1122733699429854, -0.0166033088608786, -0.0418350503858864,  0.0809510021720363, -0.9993917101510512, -0.2139048161619248,  0.7196716914796224,  0.6489783595942558,  0.5950689618839839, -0.7376256302221853, -0.5442228345597713, -0.8234113806545975, -0.6424001059348645, -0.3817524674245201, -0.8801262923106541
  VLOAD_64(v2,     0xbfc6c7abd11a2788,  0x3fbcbdf2941de8b0,  0xbf91007532405e80,  0xbfa56b675a77c100,  0x3fb4b93472e84630,  0xbfeffb0452dfc0ba,  0xbfcb613ba6efa978,  0x3fe7078ced586224,  0x3fe4c46e43c89c1c,  0x3fe30ace10450114,  0xbfe79aa110cfdc92,  0xbfe16a46018575da,  0xbfea5962d2e21a3e,  0xbfe48e8aaabdfd5e,  0xbfd86ea1e6b05c10,  0xbfec29fe9d3a5e2c);
  //               0.6809772463364707, -0.3512739833826983, -0.3746023351803702, -0.7912172181005324,  0.8292434726428350,  0.4103374079106952, -0.0850673796598582, -0.5834949864830523, -0.9215678788036654,  0.4412210589054084,  0.3537359089001260, -0.4889461402031243,  0.2341577339668230,  0.0593866008892341, -0.4825773777931026,  0.8989772522533539
  VLOAD_64(v3,     0x3fe5ca90cb4aba98,  0xbfd67b45dfa41e18,  0xbfd7f97c12a6b704,  0xbfe951a6c578c3ac,  0x3fea89299b6d84b0,  0x3fda42f7d4d35178,  0xbfb5c6f9cd987320,  0xbfe2abfdad8a63b6,  0xbfed7d7beb902fcc,  0x3fdc3cf7409388b4,  0x3fd6a39bf009666c,  0xbfdf4ae4c06b61e4,  0x3fcdf8e170bf19c0,  0x3fae67eba9479c60,  0xbfdee28c39da4ac0,  0x3fecc46bf148d5ca);
  //               0.2213384305747967, -0.6962211546566610, -0.0896076892809434, -0.1334142611967066,  0.1988436916560323, -0.3391391007320459, -0.6137202819751713,  0.6759552396290200, -0.7798663937316326, -0.1025181838739857,  0.5296250728149803,  0.8832422045338422,  0.8373555508937671, -0.8622529212135799,  0.4241832213372883,  0.7769982087360683
  VLOAD_64(v1,     0x3fcc54d154555708,  0xbfe6477196411436,  0xbfb6f0878eee8940,  0xbfc113b7f0547630,  0x3fc973b5c856db48,  0xbfd5b4747c9c185c,  0xbfe3a398b77f3552,  0x3fe5a16ce1f8870a,  0xbfe8f4aa5e0a7552,  0xbfba3ea1b6fbece0,  0x3fe0f2b047dc3902,  0x3fec438527dd6ef6,  0x3feacb9dde46cf34,  0xbfeb9793702fc4f0,  0x3fdb25d161c9f510,  0x3fe8dd2b58f24dc8);
  asm volatile("vfnmsac.vv v1, v2, v3");
  //               0.3425309161602823, -0.6567824407689892, -0.0958273275519495, -0.1665148733821233,  0.1317156015009752,  0.0709487030987733, -0.6319166041826899,  1.0958800635211576, -0.1817887834908719, -0.3650751413581792,  0.7905497455496533,  0.6171465501654385,  1.0301636939103409, -0.8241029625112244,  0.2399581166415165,  1.5682117246334322
  VCMP_U64(3, v1,  0x3fd5ec06cab1bfc9,  0xbfe5045c9bf61361,  0xbfb88823c5e61162,  0xbfc5505bffbca57e,  0x3fc0dc0e8c68ea87,  0x3fb229b1b780ba72,  0xbfe438a92b9872ef,  0x3ff188b9889296a1,  0xbfc744dad7efbbd3,  0xbfd75d64202dd23c,  0x3fe94c2efadfe675,  0x3fe3bfaa1f3997d0,  0x3ff07b8cecedf189,  0xbfea5f0d2d10b7b0,  0x3fceb6f293b149df,  0x3ff917652d6811d0);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE2(void) {
  VSET(16, e16, m1);
  //               0.3474, -0.9888,  0.2810,  0.4199,  0.1704, -0.3772,  0.2998,  0.7871, -0.2527, -0.8618,  0.2646,  0.5488, -0.3184, -0.3508, -0.3589, -0.3914
  VLOAD_16(v2,     0x358f,  0xbbe9,  0x347f,  0x36b8,  0x3174,  0xb609,  0x34cc,  0x3a4c,  0xb40b,  0xbae5,  0x343c,  0x3864,  0xb518,  0xb59d,  0xb5be,  0xb643);
  //               0.0417,  0.3862, -0.9619, -0.5659,  0.1731,  0.4827,  0.7334, -0.7271, -0.9814,  0.8003, -0.4836,  0.5234, -0.8540, -0.2036, -0.8823,  0.2603
  VLOAD_16(v3,     0x2958,  0x362e,  0xbbb2,  0xb887,  0x318a,  0x37b9,  0x39de,  0xb9d1,  0xbbda,  0x3a67,  0xb7bd,  0x3830,  0xbad5,  0xb284,  0xbb0f,  0x342a);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.2739,  0.2146,  0.5264, -0.8853,  0.8877, -0.6748, -0.7563, -0.9634,  0.7451, -0.5166,  0.0698,  0.4790, -0.0681, -0.9746,  0.2129,  0.9072
  VLOAD_16(v1,     0xb462,  0x32de,  0x3836,  0xbb15,  0x3b1a,  0xb966,  0xba0d,  0xbbb5,  0x39f6,  0xb822,  0x2c77,  0x37aa,  0xac5b,  0xbbcc,  0x32d0,  0x3b42);
  asm volatile("vfnmsac.vv v1, v2, v3, v0.t");
  //              -0.2739,  0.5967,  0.5264, -0.6475,  0.8877, -0.4927, -0.7563, -0.3911,  0.7451,  0.1733,  0.0698,  0.1917, -0.0681, -1.0459,  0.2129,  1.0088
  VCMP_U16(4, v1,  0xb462,  0x38c6,  0x3836,  0xb92e,  0x3b1a,  0xb7e2,  0xba0d,  0xb642,  0x39f6,  0x318a,  0x2c77,  0x3223,  0xac5b,  0xbc2f,  0x32d0,  0x3c09);

  VSET(16, e32, m1);
  //               0.11577118, -0.10074481,  0.13861528,  0.44782066,  0.42196107, -0.67597556,  0.34948668, -0.87903690, -0.34136006, -0.19722189,  0.76997000, -0.68663412,  0.45603558,  0.60629857, -0.86984915, -0.08019307
  VLOAD_32(v2,     0x3ded1971,  0xbdce534c,  0x3e0df12a,  0x3ee548c0,  0x3ed80b48,  0xbf2d0cbc,  0x3eb2efeb,  0xbf610890,  0xbeaec6bf,  0xbe49f489,  0x3f451cc1,  0xbf2fc741,  0x3ee97d7f,  0x3f1b3662,  0xbf5eae6f,  0xbda43c43);
  //              -0.38970658,  0.40460527,  0.69067985, -0.98108912,  0.47494572, -0.34277225, -0.54462087, -0.90492284,  0.60100728, -0.02819708, -0.46859986,  0.87238866,  0.46812481,  0.49922746,  0.97036403,  0.04279163
  VLOAD_32(v3,     0xbec7879f,  0x3ecf286c,  0x3f30d065,  0xbf7b28a8,  0x3ef32c16,  0xbeaf7fd8,  0xbf0b6c46,  0xbf67a906,  0x3f19db9d,  0xbce6fd92,  0xbeefec52,  0x3f5f54dd,  0x3eefae0e,  0x3eff9abe,  0x3f7869c7,  0x3d2f4647);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               0.79804420, -0.70010293, -0.51047552,  0.38566175,  0.15318950,  0.15531392, -0.20705318, -0.82493448,  0.12047531,  0.57526720,  0.23939800, -0.19725421,  0.15403098,  0.03931713, -0.45930895, -0.15395784
  VLOAD_32(v1,     0x3f4c4ca0,  0xbf3339f2,  0xbf02ae86,  0x3ec57575,  0x3e1cddb5,  0x3e1f0a9d,  0xbe5405c0,  0xbf532ee8,  0x3df6bbc3,  0x3f1344b6,  0x3e7524c0,  0xbe49fd02,  0x3e1dba4c,  0x3d210b00,  0xbeeb2a8b,  0xbe1da720);
  asm volatile("vfnmsac.vv v1, v2, v3, v0.t");
  //               0.79804420, -0.65934104, -0.51047552,  0.82501376,  0.15318950, -0.07639174, -0.20705318, -1.62039506,  0.12047531,  0.56970614,  0.23939800,  0.40175763,  0.15403098, -0.26336378, -0.45930895, -0.15052626
  VCMP_U32(5, v1,  0x3f4c4ca0,  0xbf28ca93,  0xbf02ae86,  0x3f53341a,  0x3e1cddb5,  0xbd9c7345,  0xbe5405c0,  0xbfcf691b,  0x3df6bbc3,  0x3f11d843,  0x3e7524c0,  0x3ecdb32c,  0x3e1dba4c,  0xbe86d79e,  0xbeeb2a8b,  0xbe1a238e);

  VSET(16, e64, m1);
  //              -0.1779684802061718,  0.1122733699429854, -0.0166033088608786, -0.0418350503858864,  0.0809510021720363, -0.9993917101510512, -0.2139048161619248,  0.7196716914796224,  0.6489783595942558,  0.5950689618839839, -0.7376256302221853, -0.5442228345597713, -0.8234113806545975, -0.6424001059348645, -0.3817524674245201, -0.8801262923106541
  VLOAD_64(v2,     0xbfc6c7abd11a2788,  0x3fbcbdf2941de8b0,  0xbf91007532405e80,  0xbfa56b675a77c100,  0x3fb4b93472e84630,  0xbfeffb0452dfc0ba,  0xbfcb613ba6efa978,  0x3fe7078ced586224,  0x3fe4c46e43c89c1c,  0x3fe30ace10450114,  0xbfe79aa110cfdc92,  0xbfe16a46018575da,  0xbfea5962d2e21a3e,  0xbfe48e8aaabdfd5e,  0xbfd86ea1e6b05c10,  0xbfec29fe9d3a5e2c);
  //               0.6809772463364707, -0.3512739833826983, -0.3746023351803702, -0.7912172181005324,  0.8292434726428350,  0.4103374079106952, -0.0850673796598582, -0.5834949864830523, -0.9215678788036654,  0.4412210589054084,  0.3537359089001260, -0.4889461402031243,  0.2341577339668230,  0.0593866008892341, -0.4825773777931026,  0.8989772522533539
  VLOAD_64(v3,     0x3fe5ca90cb4aba98,  0xbfd67b45dfa41e18,  0xbfd7f97c12a6b704,  0xbfe951a6c578c3ac,  0x3fea89299b6d84b0,  0x3fda42f7d4d35178,  0xbfb5c6f9cd987320,  0xbfe2abfdad8a63b6,  0xbfed7d7beb902fcc,  0x3fdc3cf7409388b4,  0x3fd6a39bf009666c,  0xbfdf4ae4c06b61e4,  0x3fcdf8e170bf19c0,  0x3fae67eba9479c60,  0xbfdee28c39da4ac0,  0x3fecc46bf148d5ca);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               0.2213384305747967, -0.6962211546566610, -0.0896076892809434, -0.1334142611967066,  0.1988436916560323, -0.3391391007320459, -0.6137202819751713,  0.6759552396290200, -0.7798663937316326, -0.1025181838739857,  0.5296250728149803,  0.8832422045338422,  0.8373555508937671, -0.8622529212135799,  0.4241832213372883,  0.7769982087360683
  VLOAD_64(v1,     0x3fcc54d154555708,  0xbfe6477196411436,  0xbfb6f0878eee8940,  0xbfc113b7f0547630,  0x3fc973b5c856db48,  0xbfd5b4747c9c185c,  0xbfe3a398b77f3552,  0x3fe5a16ce1f8870a,  0xbfe8f4aa5e0a7552,  0xbfba3ea1b6fbece0,  0x3fe0f2b047dc3902,  0x3fec438527dd6ef6,  0x3feacb9dde46cf34,  0xbfeb9793702fc4f0,  0x3fdb25d161c9f510,  0x3fe8dd2b58f24dc8);
  asm volatile("vfnmsac.vv v1, v2, v3, v0.t");
  //               0.2213384305747967, -0.6567824407689892, -0.0896076892809434, -0.1665148733821233,  0.1988436916560323,  0.0709487030987733, -0.6137202819751713,  1.0958800635211576, -0.7798663937316326, -0.3650751413581792,  0.5296250728149803,  0.6171465501654385,  0.8373555508937671, -0.8241029625112244,  0.4241832213372883,  1.5682117246334322
  VCMP_U64(6, v1,  0x3fcc54d154555708,  0xbfe5045c9bf61361,  0xbfb6f0878eee8940,  0xbfc5505bffbca57e,  0x3fc973b5c856db48,  0x3fb229b1b780ba72,  0xbfe3a398b77f3552,  0x3ff188b9889296a1,  0xbfe8f4aa5e0a7552,  0xbfd75d64202dd23c,  0x3fe0f2b047dc3902,  0x3fe3bfaa1f3997d0,  0x3feacb9dde46cf34,  0xbfea5f0d2d10b7b0,  0x3fdb25d161c9f510,  0x3ff917652d6811d0);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE3(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                             -0.4771
  BOX_HALF_IN_DOUBLE(dscalar_16,  0xb7a2);
  //              -0.6172,  0.8584, -0.1088, -0.6719,  0.3579,  0.5889,  0.1724, -0.5239, -0.5732, -0.6167,  0.8271, -0.7334,  0.3489, -0.7607, -0.7788, -0.5264
  VLOAD_16(v2,     0xb8f0,  0x3ade,  0xaef7,  0xb960,  0x35ba,  0x38b6,  0x3184,  0xb831,  0xb896,  0xb8ef,  0x3a9e,  0xb9de,  0x3595,  0xba16,  0xba3b,  0xb836);
  //               0.0186,  0.9351,  0.6201,  0.9463,  0.2512,  0.5786,  0.9424, -0.5132, -0.7646,  0.0194, -0.2507, -0.2905,  0.3452, -0.7803, -0.7666, -0.1387
  VLOAD_16(v1,     0x24c1,  0x3b7b,  0x38f6,  0x3b92,  0x3405,  0x38a1,  0x3b8a,  0xb81b,  0xba1e,  0x24f6,  0xb403,  0xb4a6,  0x3586,  0xba3e,  0xba22,  0xb070);
  asm volatile("vfnmsac.vf v1, %[A], v2" :: [A] "f" (dscalar_16));
  //              -0.2759,  1.3447,  0.5684,  0.6260,  0.4219,  0.8594,  1.0244, -0.7632, -1.0381, -0.2749,  0.1438, -0.6406,  0.5117, -1.1426, -1.1387, -0.3899
  VCMP_U16(7, v1,  0xb46a,  0x3d61,  0x388c,  0x3902,  0x36c0,  0x3ae0,  0x3c19,  0xba1b,  0xbc27,  0xb466,  0x309a,  0xb920,  0x3818,  0xbc93,  0xbc8d,  0xb63d);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -0.73549986
  BOX_FLOAT_IN_DOUBLE(dscalar_32,  0xbf3c49b8);
  //               0.74252719,  0.73023552,  0.75118375,  0.04020444, -0.77184784, -0.41120139, -0.57577437, -0.15976480, -0.05041125,  0.42673740,  0.88473374, -0.49891368, -0.84324479, -0.26009968, -0.01877740, -0.13754985
  VLOAD_32(v2,     0x3f3e1643,  0x3f3af0b7,  0x3f404d94,  0x3d24ad6a,  0xbf4597d2,  0xbed288fd,  0xbf1365f3,  0xbe239962,  0xbd4e7c07,  0x3eda7d53,  0x3f627de9,  0xbeff719d,  0xbf57dee4,  0xbe852bc9,  0xbc99d30f,  0xbe0cd9de);
  //               0.89538908,  0.68592542,  0.67501348,  0.08327232,  0.28473541, -0.93230879, -0.77235961, -0.92498165, -0.55227244,  0.97729182,  0.28253901,  0.45306230, -0.50359881,  0.40307203, -0.65891176, -0.59297264
  VLOAD_32(v1,     0x3f653838,  0x3f2f98cf,  0x3f2ccdaf,  0x3daa8aad,  0x3e91c8d7,  0xbf6eabca,  0xbf45b95c,  0xbf6ccb99,  0xbf0d61ba,  0x3f7a2fcc,  0x3e90a8f4,  0x3ee7f7c8,  0xbf00ebda,  0x3ece5f75,  0xbf28ae71,  0xbf17cd0e);
  asm volatile("vfnmsac.vf v1, %[A], v2" :: [A] "f" (dscalar_32));
  //               1.44151771,  1.22301352,  1.22750902,  0.11284268, -0.28295860, -1.23474741, -1.19584155, -1.04248869, -0.58934993,  1.29115713,  0.93326056,  0.08611137, -1.12380528,  0.21176875, -0.67272252, -0.69414055
  VCMP_U32(8, v1,  0x3fb883a7,  0x3f9c8bb5,  0x3f9d1f04,  0x3de71a10,  0xbe90dff2,  0xbf9e0c34,  0xbf991156,  0xbf857045,  0xbf16dfa3,  0x3fa544a3,  0x3f6eea2a,  0x3db05b27,  0xbf8fd8da,  0x3e58d9e8,  0xbf2c378b,  0xbf31b332);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.5178244899339752
  BOX_DOUBLE_IN_DOUBLE(dscalar_64,  0x3fe09204aa2ab2a0);
  //                0.8646249694399413,  0.0049558737185129,  0.9278624830778543, -0.8820434014846885,  0.9252937592855630, -0.0640564429957495, -0.9483662154664578,  0.6036726974274773,  0.6321354499926264,  0.8250130840364809,  0.1494192541908572,  0.0196333207724690, -0.2272946521816408,  0.9289723385226867, -0.5162193242581365, -0.3917544955022987
  VLOAD_64(v2,      0x3febab01fbe195e4,  0x3f744c9c38b4b600,  0x3fedb10ca98026d0,  0xbfec39b31560f050,  0x3fed9c01a86a6166,  0xbfb06600c7c3cc10,  0xbfee59041b01e946,  0x3fe35149679e0d42,  0x3fe43a741f8b89d2,  0x3fea6681d6d6ae5e,  0x3fc3202b8d123b90,  0x3f941ac1da84be40,  0xbfcd17fdbcd68200,  0x3fedba24329afe9c,  0xbfe084de63680fb2,  0xbfd91281728f9314);
  //                0.3888129269587612, -0.8225750100551035,  0.8430062678626642, -0.6316792665412014, -0.6696614660277347,  0.6130084754374303, -0.2295750183537659,  0.1572393304616742, -0.7542147373874082,  0.6149250820738357,  0.1236692515687874,  0.9290168852760794, -0.0433411597165929, -0.8422695068160440,  0.6519328829008422, -0.3347506024828231
  VLOAD_64(v1,      0x3fd8e24f9d6331d4,  0xbfea5288d3d6317c,  0x3feaf9e847d9618e,  0xbfe436b76feb621e,  0xbfe56ddde1ff608c,  0x3fe39dc3f345962e,  0xbfcd62b6d5e76d58,  0x3fc4206b1afd2970,  0xbfe82286f1e7af48,  0x3fe3ad775d9fe964,  0x3fbfa8c9bf023cb0,  0x3fedba819e762954,  0xbfa630cfff1b61a0,  0xbfeaf3df2e462cb6,  0x3fe4dca25967e02c,  0xbfd56c8dca7eb8ac);
  asm volatile("vfnmsac.vf v1, %[A], v2" :: [A] "f" (dscalar_64));
  //               -0.0589110568256553, -0.8251412828355696,  0.3625363508340025, -0.1749355920677641, -1.1488012349688719,  0.6461784703586890,  0.2615122334407671, -0.1553571761707763, -1.0815499543490239,  0.1877131026437891,  0.0462963024810918,  0.9188502709613655,  0.0743575776140855, -1.3233141341743264,  0.9192438911788732, -0.1318905306700034
  VCMP_U64(9, v1,   0xbfae29970ce0c2e6,  0xbfea678eb10b76d9,  0x3fd733cbaa9c5dc5,  0xbfc6644a1b6b315b,  0xbff2617d675cbb41,  0x3fe4ad7e78b23c6a,  0x3fd0bc9dce8872e3,  0xbfc3e2be736d1b43,  0xbff14e07532eb5a9,  0x3fc806fba27160c3,  0x3fa7b4262229fd93,  0x3fed6738aef664ca,  0x3fb30919240ff186,  0xbff52c4b7109d007,  0x3fed6a722a352743,  0xbfc0e1c9f5f09ba4);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE4(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                             -0.4771
  BOX_HALF_IN_DOUBLE(dscalar_16,  0xb7a2);
  //               -0.6172,  0.8584, -0.1088, -0.6719,  0.3579,  0.5889,  0.1724, -0.5239, -0.5732, -0.6167,  0.8271, -0.7334,  0.3489, -0.7607, -0.7788, -0.5264
  VLOAD_16(v2,      0xb8f0,  0x3ade,  0xaef7,  0xb960,  0x35ba,  0x38b6,  0x3184,  0xb831,  0xb896,  0xb8ef,  0x3a9e,  0xb9de,  0x3595,  0xba16,  0xba3b,  0xb836);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                0.0186,  0.9351,  0.6201,  0.9463,  0.2512,  0.5786,  0.9424, -0.5132, -0.7646,  0.0194, -0.2507, -0.2905,  0.3452, -0.7803, -0.7666, -0.1387
  VLOAD_16(v1,      0x24c1,  0x3b7b,  0x38f6,  0x3b92,  0x3405,  0x38a1,  0x3b8a,  0xb81b,  0xba1e,  0x24f6,  0xb403,  0xb4a6,  0x3586,  0xba3e,  0xba22,  0xb070);
  asm volatile("vfnmsac.vf v1, %[A], v2, v0.t" :: [A] "f" (dscalar_16));
  //                0.0186,  1.3447,  0.6201,  0.6260,  0.2512,  0.8594,  0.9424, -0.7632, -0.7646, -0.2749, -0.2507, -0.6406,  0.3452, -1.1426, -0.7666, -0.3899
  VCMP_U16(10, v1,  0x24c1,  0x3d61,  0x38f6,  0x3902,  0x3405,  0x3ae0,  0x3b8a,  0xba1b,  0xba1e,  0xb466,  0xb403,  0xb920,  0x3586,  0xbc93,  0xba22,  0xb63d);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -0.73549986
  BOX_FLOAT_IN_DOUBLE(dscalar_32,  0xbf3c49b8);
  //                0.74252719,  0.73023552,  0.75118375,  0.04020444, -0.77184784, -0.41120139, -0.57577437, -0.15976480, -0.05041125,  0.42673740,  0.88473374, -0.49891368, -0.84324479, -0.26009968, -0.01877740, -0.13754985
  VLOAD_32(v2,      0x3f3e1643,  0x3f3af0b7,  0x3f404d94,  0x3d24ad6a,  0xbf4597d2,  0xbed288fd,  0xbf1365f3,  0xbe239962,  0xbd4e7c07,  0x3eda7d53,  0x3f627de9,  0xbeff719d,  0xbf57dee4,  0xbe852bc9,  0xbc99d30f,  0xbe0cd9de);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                0.89538908,  0.68592542,  0.67501348,  0.08327232,  0.28473541, -0.93230879, -0.77235961, -0.92498165, -0.55227244,  0.97729182,  0.28253901,  0.45306230, -0.50359881,  0.40307203, -0.65891176, -0.59297264
  VLOAD_32(v1,      0x3f653838,  0x3f2f98cf,  0x3f2ccdaf,  0x3daa8aad,  0x3e91c8d7,  0xbf6eabca,  0xbf45b95c,  0xbf6ccb99,  0xbf0d61ba,  0x3f7a2fcc,  0x3e90a8f4,  0x3ee7f7c8,  0xbf00ebda,  0x3ece5f75,  0xbf28ae71,  0xbf17cd0e);
  asm volatile("vfnmsac.vf v1, %[A], v2, v0.t" :: [A] "f" (dscalar_32));
  //                0.89538908,  1.22301352,  0.67501348,  0.11284268,  0.28473541, -1.23474741, -0.77235961, -1.04248869, -0.55227244,  1.29115713,  0.28253901,  0.08611137, -0.50359881,  0.21176875, -0.65891176, -0.69414055
  VCMP_U32(11, v1,  0x3f653838,  0x3f9c8bb5,  0x3f2ccdaf,  0x3de71a10,  0x3e91c8d7,  0xbf9e0c34,  0xbf45b95c,  0xbf857045,  0xbf0d61ba,  0x3fa544a3,  0x3e90a8f4,  0x3db05b27,  0xbf00ebda,  0x3e58d9e8,  0xbf28ae71,  0xbf31b332);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.5178244899339752
  BOX_DOUBLE_IN_DOUBLE(dscalar_64,  0x3fe09204aa2ab2a0);
  //                 0.8646249694399413,  0.0049558737185129,  0.9278624830778543, -0.8820434014846885,  0.9252937592855630, -0.0640564429957495, -0.9483662154664578,  0.6036726974274773,  0.6321354499926264,  0.8250130840364809,  0.1494192541908572,  0.0196333207724690, -0.2272946521816408,  0.9289723385226867, -0.5162193242581365, -0.3917544955022987
  VLOAD_64(v2,       0x3febab01fbe195e4,  0x3f744c9c38b4b600,  0x3fedb10ca98026d0,  0xbfec39b31560f050,  0x3fed9c01a86a6166,  0xbfb06600c7c3cc10,  0xbfee59041b01e946,  0x3fe35149679e0d42,  0x3fe43a741f8b89d2,  0x3fea6681d6d6ae5e,  0x3fc3202b8d123b90,  0x3f941ac1da84be40,  0xbfcd17fdbcd68200,  0x3fedba24329afe9c,  0xbfe084de63680fb2,  0xbfd91281728f9314);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                 0.3888129269587612, -0.8225750100551035,  0.8430062678626642, -0.6316792665412014, -0.6696614660277347,  0.6130084754374303, -0.2295750183537659,  0.1572393304616742, -0.7542147373874082,  0.6149250820738357,  0.1236692515687874,  0.9290168852760794, -0.0433411597165929, -0.8422695068160440,  0.6519328829008422, -0.3347506024828231
  VLOAD_64(v1,       0x3fd8e24f9d6331d4,  0xbfea5288d3d6317c,  0x3feaf9e847d9618e,  0xbfe436b76feb621e,  0xbfe56ddde1ff608c,  0x3fe39dc3f345962e,  0xbfcd62b6d5e76d58,  0x3fc4206b1afd2970,  0xbfe82286f1e7af48,  0x3fe3ad775d9fe964,  0x3fbfa8c9bf023cb0,  0x3fedba819e762954,  0xbfa630cfff1b61a0,  0xbfeaf3df2e462cb6,  0x3fe4dca25967e02c,  0xbfd56c8dca7eb8ac);
  asm volatile("vfnmsac.vf v1, %[A], v2, v0.t" :: [A] "f" (dscalar_64));
  //                0.3888129269587612, -0.8251412828355696,  0.8430062678626642, -0.1749355920677641, -0.6696614660277347,  0.6461784703586890, -0.2295750183537659, -0.1553571761707763, -0.7542147373874082,  0.1877131026437891,  0.1236692515687874,  0.9188502709613655, -0.0433411597165929, -1.3233141341743264,  0.6519328829008422, -0.1318905306700034
  VCMP_U64(12, v1,  0x3fd8e24f9d6331d4,  0xbfea678eb10b76d9,  0x3feaf9e847d9618e,  0xbfc6644a1b6b315b,  0xbfe56ddde1ff608c,  0x3fe4ad7e78b23c6a,  0xbfcd62b6d5e76d58,  0xbfc3e2be736d1b43,  0xbfe82286f1e7af48,  0x3fc806fba27160c3,  0x3fbfa8c9bf023cb0,  0x3fed6738aef664ca,  0xbfa630cfff1b61a0,  0xbff52c4b7109d007,  0x3fe4dca25967e02c,  0xbfc0e1c9f5f09ba4);
};

int main(void) {
  enable_vec();
  enable_fp();

  TEST_CASE1();
  TEST_CASE2();
  TEST_CASE3();
  TEST_CASE4();

  EXIT_CHECK();
}
